﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Senthil.Mobile.WhereAmI;
using Rhino.Mocks;
using Rhino.Mocks.Interfaces;

namespace wamilibtest
{
    [TestClass]
    public class NotificationManagerTests
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        [TestMethod]
        public void InputMessageRecievedTest()
        {
            MockRepository mocker = new MockRepository();
            IInputMessageReceiver receiver = mocker.CreateMock<IInputMessageReceiver>();
            IRouteTracker tracker = mocker.CreateMock<IRouteTracker>();
            INotifier notifier = mocker.CreateMock<INotifier>();

            TimeSpan expectedTimeSpan = TimeSpan.FromMinutes(5);
            Location expectedLocation = new Location("TestLocation", false);
            string smsSendingUser = "User1";
            string receivingUser = smsSendingUser;
            string configuredMessageText = "Blah";

            NotificationMessage expectedMessage = new NotificationMessage()
            {
                OwnerName = "Owner",
                LocationName = expectedLocation.Name,
                DestinationLocationGroupName = "LastPost",
                DestinationTimeSpan = expectedTimeSpan
            };

            IEventRaiser eventRaiser = null;
            
            using (mocker.Record())
            {
                receiver.InputMessageReceived += null;
                eventRaiser = LastCall.IgnoreArguments().GetEventRaiser();

                Expect.Call(() => receiver.ReceiveOnlyMessage(configuredMessageText));

                Location location; TimeSpan timespan;
                Expect.Call(()=>tracker.GetLastKnownInfo(out location, out timespan)).OutRef(expectedLocation, expectedTimeSpan);
                Expect.Call(tracker.DestinationLocationGroup).Return(new LocationGroup("LastPost"));

                Expect.Call(()=>notifier.Notify(new string[] { receivingUser}, expectedMessage));
            }

            using (mocker.Playback())
            {
                NotificationManager mgr = new NotificationManager("Owner", tracker, receiver, notifier);
                mgr.NotifyUserWhenSMSInput(new string[] { smsSendingUser }, configuredMessageText);

                eventRaiser.Raise(receiver, new InputMessageReceivedEventArgs(smsSendingUser, configuredMessageText));
            }
        }

        [TestMethod]
        public void InputMessageRecievedNotConfiguredMessageTest()
        {
            MockRepository mocker = new MockRepository();
            IInputMessageReceiver receiver = mocker.CreateMock<IInputMessageReceiver>();
            IRouteTracker tracker = mocker.CreateMock<IRouteTracker>();
            INotifier notifier = mocker.CreateMock<INotifier>();

            TimeSpan expectedTimeSpan = TimeSpan.FromMinutes(5);
            Location expectedLocation = new Location("TestLocation", false);
            string smsSendingUser = "User1";
            string receivingUser = smsSendingUser;
            string configuredMessageText = "Blah";

            IEventRaiser eventRaiser = null;

            using (mocker.Record())
            {
                receiver.InputMessageReceived += null;
                eventRaiser = LastCall.IgnoreArguments().GetEventRaiser();

                Expect.Call(() => receiver.ReceiveOnlyMessage(configuredMessageText));
            }

            using (mocker.Playback())
            {
                NotificationManager mgr = new NotificationManager("Owner", tracker, receiver, notifier);
                mgr.NotifyUserWhenSMSInput(new string[] { smsSendingUser }, configuredMessageText);

                eventRaiser.Raise(receiver, new InputMessageReceivedEventArgs(smsSendingUser, "Some Random Message"));
            }
        }

        [TestMethod]
        public void InputMessageRecievedNotConfiguredUser()
        {
            MockRepository mocker = new MockRepository();
            IInputMessageReceiver receiver = mocker.CreateMock<IInputMessageReceiver>();
            IRouteTracker tracker = mocker.CreateMock<IRouteTracker>();
            INotifier notifier = mocker.CreateMock<INotifier>();

            TimeSpan expectedTimeSpan = TimeSpan.FromMinutes(5);
            Location expectedLocation = new Location("TestLocation", false);
            string smsSendingUser = "User1";
            string receivingUser = smsSendingUser;
            string configuredMessageText = "Blah";

            IEventRaiser eventRaiser = null;

            using (mocker.Record())
            {
                receiver.InputMessageReceived += null;
                eventRaiser = LastCall.IgnoreArguments().GetEventRaiser();

                Expect.Call(() => receiver.ReceiveOnlyMessage(configuredMessageText));
            }

            using (mocker.Playback())
            {
                NotificationManager mgr = new NotificationManager("Owner", tracker, receiver, notifier);
                mgr.NotifyUserWhenSMSInput(new string[] { smsSendingUser }, configuredMessageText);

                eventRaiser.Raise(receiver, new InputMessageReceivedEventArgs("Some Random User", configuredMessageText));
            }
        }

        [TestMethod]
        public void TestNotificationMessageAtDestination()
        {
            string ownerName = "Senthil";
            string destinationLocationName = "DestinationLocation";
            string destinationLocationGroupName =  "DestinationGroup";

            NotificationMessage message = new NotificationMessage()
            {
                OwnerName = ownerName,
                DestinationTimeSpan = TimeSpan.Zero,
                DestinationLocationGroupName = destinationLocationGroupName,
                LocationGroupName = destinationLocationGroupName,
                LocationName = destinationLocationName
            };

            Assert.AreEqual(ownerName + " is at " + destinationLocationGroupName + "(" + destinationLocationName + ")",
                message.ToString());
        }
    }
}
